﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using VASJ.Model;
using System.Web.Profile;






namespace VASJ.Service.Library.Manager
{
    public class UserManager : BaseManager
    {
        /// <summary>
        /// Init
        /// </summary>
        /// <param name="_ApplicationName"></param>
        public UserManager(string _ApplicationName)
            : base(_ApplicationName)
        {
        }

        #region "Private "
        /// <summary>
        /// Get OwnerisUser
        /// </summary>
        /// <param name="ownerid"></param>
        /// <returns></returns>
        private bool _GetOwnerisUser(string ownerid)
        {
            bool ret = true;

            var _org = this.mdb.AHSOrganizations.Where(o => o.Id == Guid.Parse(ownerid)).FirstOrDefault();

            // If Organization is Esxits 
            if (_org != null)
            {
                ret = false;
            }

            return ret;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="Ownerid"></param>
        private void _SetOwnerAspnet_MembershipByOrganization(string orgId, string Ownerid)
        {
            try
            {
                var _owner = new AHSDbContext.AHSAspnetMembership();
                var _user = this.mdb.AHSAspnetMemberships.Where(m => m.Userid == Guid.Parse(orgId)).FirstOrDefault();

                if (_user == null)
                {
                    _owner.Userid = Guid.Parse(orgId);
                    _owner.Ownerid = Guid.Parse(Ownerid);
                    _owner.Ownerisuser = false;

                    this.mdb.AHSAspnetMemberships.InsertOnSubmit(_owner);
                }
                else
                {
                    _user.Ownerid = Guid.Parse(Ownerid);
                    _user.Ownerisuser = false;

                    this.mdb.SubmitChanges();

                    //Add User known Organ: Hiện tại chưa có phần User known Organ trong CS
                    //if (_user.Ownerid != null)
                    //{
                    //    OrganizationManager om = new OrganizationManager();
                    //    om.AddKnown(Guid.Parse(orgId), _user.Ownerid.Value);
                    //}
                }

            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] Unable to _Set Owner Aspnet_Membership By Organization {0}", ex);
            }

        }
        #endregion
        /// <summary>
        /// CreateUser
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="email"></param>
        /// <param name="passwordQuestion"></param>
        /// <param name="passwordAnswer"></param>
        /// <param name="isApproved"></param>
        /// <param name="providerUserKey"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            try
            {
                Common cm = new Common(this.ApplicationName);
                UserManager um = new UserManager(this.ApplicationName);

                //Check the exist user
                MembershipUser mu = Membership.GetUser(username);

                bool isNew = (mu == null);

                if (mu == null)
                {
                    mu = Membership.Provider.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status);
                }
                else
                {
                    status = MembershipCreateStatus.Success;
                }

                if (this.ApplicationName != "AHS")
                {
                    //Add user into Empowering organization CS
                    var findOrg = (from orgs in this.mdb.AHSOrganizationEmpowerForApps
                                   where orgs.ApplicationName == this.ApplicationName
                                   select orgs.OrganID).Distinct();

                    if (findOrg != null && findOrg.Count() > 0)
                    {
                        var org = findOrg.FirstOrDefault();

                        if (org != null && !um.IsUserInOrganizationOutside(username, org))
                        {
                            //Add user to organization
                            AHSUsersInOrganization uio = new AHSUsersInOrganization();

                            uio.OrgId = org;
                            uio.UserId = Guid.Parse(mu.ProviderUserKey.ToString());
                            uio.IsInvite = false;
                            uio.Status = 1;

                            this.mdb.AHSUsersInOrganizations.InsertOnSubmit(uio);

                            this.mdb.SubmitChanges();
                        }
                    }
                }

                // Add user into Application
                this.AddUserToApplication(username);

                return mu;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.CreateUser {0}", ex);

                status = MembershipCreateStatus.ProviderError;

                return null;
            }
        }

        /// <summary>
        /// Delete User from Application
        /// </summary>
        /// <returns></returns>
        public bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            try
            {
                //// Delete User In project
                //var uips = from uip in this.mdb.AHSUserInProjects
                //           where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower())
                //           select uip;

                //this.mdb.AHSUserInProjects.DeleteAllOnSubmit(uips);

                //// Delete User in Project via Organization
                //var uios = from oip in this.mdb.AHSOrganizationInProjects
                //           join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                //           where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uio.AHSAspnetUser.Username.ToLower() == username.ToLower())
                //           select uio;

                //this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(uios);

                //this.mdb.SubmitChanges();

                this.RemoveUserFromApplication(username);

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.DeleteUser {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Get UserID by UserName
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public Guid GetUserID(string userName)
        {
            try
            {
                MembershipUser mu = Membership.GetUser(userName);

                if (mu != null) return Guid.Parse(mu.ProviderUserKey.ToString()); else return Guid.Empty;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserID {0}", ex);

                return Guid.Empty;
            }
        }

        /// <summary>
        /// Get user list in application for check user exist in application, all username become ToLower
        /// </summary>
        /// <returns></returns>
        public List<string> GetListUserNameInApplication()
        {
            try
            {
                // Get user list inside project and inside project via organization
                List<string> list_uip = new List<string>();

                //var uips = ((from uip in this.mdb.AHSUserInProjects
                //             where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.Status.HasValue) && (uip.Status.Value == 1) && (uip.AHSAspnetMembership_Userid.Isapproved.HasValue && uip.AHSAspnetMembership_Userid.Isapproved.Value == 1 && uip.AHSAspnetMembership_Userid.Islockedout.Value == 0)
                //             select uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower())
                //           .Union(from oip in this.mdb.AHSOrganizationInProjects
                //                  join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                //                  where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue) && (uio.Status.Value == 1) && (uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.HasValue && uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.Value == 1 && oip.AHSAspnetMembership.Islockedout.Value == 0)
                //                  select uio.AHSAspnetUser.Username.ToLower())).Distinct();
                var uias = (from uia in this.mdb.AHSUserInApplications
                            where uia.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                            select uia.AHSAspnetUser.Username.ToLower()).Distinct();

                foreach (var uip in uias)
                {
                    list_uip.Add(uip);
                }

                return list_uip;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListUserNameInApplication {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get All User for Application
        /// </summary>
        /// <returns></returns>
        public Dictionary<Guid, User> GetAllUsers()
        {
            // Get all user in ApplicationName
            try
            {
                Dictionary<Guid, User> list = new Dictionary<Guid, User>();

                //var users = (from oip in this.mdb.AHSOrganizationInProjects
                //             join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                //             where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue) && (uio.Status.Value == 1) && (uio.AHSAspnetUser.AHSAspnetMembership.Islockedout.Value == 0)
                //             select new { userid = uio.AHSAspnetUser.Userid, username = uio.AHSAspnetUser.Username, Email = uio.AHSAspnetUser.AHSAspnetMembership.Email, Isapproved = uio.AHSAspnetUser.AHSAspnetMembership.Isapproved }
                //            ).Union(from uip in this.mdb.AHSUserInProjects
                //                    where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.Status.HasValue) && (uip.Status.Value == 1) && (uip.AHSAspnetMembership_Userid.Islockedout.Value == 0)
                //                    select new { userid = uip.Userid, username = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username, Email = uip.AHSAspnetMembership_Userid.Email, Isapproved = uip.AHSAspnetMembership_Userid.Isapproved }
                //            ).Distinct();

                var users = (from uia in this.mdb.AHSUserInApplications
                             where uia.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                             select new { userid = uia.UserID, username = uia.AHSAspnetUser.Username, Email = uia.AHSAspnetUser.AHSAspnetMembership.Email, Isapproved = uia.AHSAspnetUser.AHSAspnetMembership.Isapproved }).Distinct();

                foreach (var item in users)
                {
                    AHSModel.User _user = new User();
                    _user.UserId = item.userid;
                    _user.UserName = item.username;
                    _user.Email = item.Email;
                    _user.ApplicationName = this.ApplicationName;
                    _user.IsApproved = item.Isapproved.Value == 1 ? true : false;

                    // Get profile of User
                    ProfileBase pb = ProfileBase.Create(item.username);

                    var phone = pb.GetPropertyValue("Phone");

                    if (phone != null)
                        _user.Phone = phone.ToString();
                    else
                        _user.Phone = "";

                    var name = pb.GetPropertyValue("Name");

                    if (name != null)
                        _user.Name = name.ToString();
                    else
                        _user.Name = "";

                    list.Add(_user.UserId, _user);
                }

                return list;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetAllUsers error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get user list exist inside project not via organization
        /// </summary>
        /// <returns></returns>
        public List<string> GetListUserNameInApplicationNotViaOrganization()
        {
            try
            {
                List<string> list_uip = new List<string>();

                // Get user list inside project
                var uias = (from uia in this.mdb.AHSUserInApplications
                            where uia.ApplicationName.ToLower() == this.ApplicationName.ToLower() && (uia.AHSAspnetUser.AHSAspnetMembership.Isapproved.HasValue && uia.AHSAspnetUser.AHSAspnetMembership.Isapproved.Value == 1) && (uia.AHSAspnetUser.AHSAspnetMembership.Islockedout.Value == 0)
                            select uia.AHSAspnetUser.Username.ToLower()).Distinct();

                foreach (var uip in uias)
                {
                    list_uip.Add(uip);
                }

                return list_uip;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListUserNameInApplicationNotViaOrganization {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get user list exist inside project only via organization
        /// </summary>
        /// <returns></returns>
        public List<string> GetListUserNameInApplicationOnlyViaOrganization()
        {
            try
            {
                List<string> list_uip = new List<string>();

                // Get user list inside project via organization
                var uips = (from oip in this.mdb.AHSOrganizationInProjects
                            join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                            where oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() && oip.Status.HasValue && oip.Status.Value == 1 && uio.Status.HasValue && uio.Status.Value == 1 && (uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.HasValue && uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.Value == 1 && uio.AHSAspnetUser.AHSAspnetMembership.Islockedout.Value == 0)
                            select uio.AHSAspnetUser.Username.ToLower()).Distinct();

                foreach (var uip in uips)
                {
                    list_uip.Add(uip);
                }

                return list_uip;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListUserNameInApplicationOnlyViaOrganization {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get this user list not in any organization of application
        /// </summary>
        /// <returns></returns>
        /// Modify: Hoang Van Tai: Try Catch 
        public Dictionary<Guid, User> GetUsersNotInAnyOrgan()
        {
            try
            {
                Dictionary<Guid, User> list = new Dictionary<Guid, User>();

                List<string> uips = this.GetListUserNameInApplicationNotViaOrganization();
                List<string> uios = this.GetListUserNameInApplicationOnlyViaOrganization();

                var users = from user in this.mdb.AHSAspnetUsers
                            where uips.Contains(user.Username.ToLower()) && !uios.Contains(user.Username.ToLower())
                            select user;

                foreach (var user in users)
                {
                    User _user = new User();

                    _user.UserId = user.Userid;
                    _user.UserName = user.Username;
                    _user.Email = user.AHSAspnetMembership.Email;
                    _user.ApplicationName = this.ApplicationName;
                    _user.IsApproved = user.AHSAspnetMembership.Isapproved.Value == 1 ? true : false;

                    //Get profile of User
                    ProfileBase pb = ProfileBase.Create(user.Username);

                    var phone = pb.GetPropertyValue("Phone");

                    if (phone != null)
                        _user.Phone = phone.ToString();
                    else
                        _user.Phone = "";

                    var name = pb.GetPropertyValue("Name");

                    if (name != null)
                        _user.Name = name.ToString();
                    else
                        _user.Name = "";

                    list.Add(_user.UserId, _user);
                }

                return list;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUsersNotInAnyOrgan error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<UserInOrganization> GetInviteOrganizationsListBySA(string userId, ref string msgError)
        {
            try
            {
                List<UserInOrganization> ret = new List<UserInOrganization>();

                var query = (from uio in this.mdb.AHSUsersInOrganizations
                             join org in this.mdb.AHSOrganizations on uio.OrgId equals org.Id
                             join uip in this.mdb.AHSOrganizationInProjects on org.Id equals uip.Orgid
                             where (uio.UserId == Guid.Parse(userId) && uio.IsInvite == true &&
                                     (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                     (uio.Status == -1 || uio.Status == null))
                             orderby (org.Name)
                             select new { UserId = uio.UserId, OrgId = uio.OrgId, OrgName = org.Name, RoleId = uio.RoleId, IsInvite = uio.IsInvite, Status = uio.Status, UserInviteId = uio.UserInvite }).Distinct();

                foreach (var item in query)
                {
                    UserInOrganization org;
                    org = new UserInOrganization();

                    org.UserId = item.UserId;
                    org.OrgId = item.OrgId;
                    org.OrgName = item.OrgName;
                    org.IsInvite = item.IsInvite;
                    org.Status = item.Status;
                    org.UserInviteId = item.UserInviteId;
                    org.RoleId = item.RoleId;

                    ret.Add(org);
                    org = null;

                }
                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetInviteOrganizationsListBySA error {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// Check User exists inside project
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="projectID"></param>
        /// <returns></returns>
        public bool IsUserInProject(string userName, int projectID)
        {
            try
            {
                var uips = ((from uip in this.mdb.AHSUserInProjects
                             where uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() && uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == userName.ToLower() && uip.Status.HasValue && uip.Status.Value == 1 && uip.Projectid == projectID
                             select uip.Projectid)
                           .Union(from oip in this.mdb.AHSOrganizationInProjects
                                  join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                  where oip.Status.HasValue && oip.Status.Value == 1 && uio.Status.HasValue && uio.Status.Value == 1 && uio.AHSAspnetUser.Username.ToLower() == userName.ToLower() && oip.Projectid == projectID
                                  select oip.Projectid)).Distinct();

                return (uips != null && uips.Count() > 0);
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsUserInProject {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check user exists in Organization which not in application, not check user joined organization or no
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="OrgID"></param>
        /// <returns></returns>
        public bool IsUserInOrganizationOutside(string userName, Guid OrgID)
        {
            try
            {
                var uios = from uio in this.mdb.AHSUsersInOrganizations
                           where uio.OrgId == OrgID && uio.AHSAspnetUser.Username.ToLower() == userName.ToLower()
                           select uio.UserId;

                return uios != null && uios.Count() > 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsUserInOrganizationOutside {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check User exists inside Organization
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="OrgID"></param>
        /// <returns></returns>
        public bool IsUserInOrganization(string userName, Guid OrgID)
        {
            try
            {
                List<Guid> lst_orgs = (new OrganizationManager(this.ApplicationName)).GetListOrganizationIDInApplication();

                var uios = (from uio in this.mdb.AHSUsersInOrganizations
                            where uio.OrgId == OrgID && uio.AHSAspnetUser.Username.ToLower() == userName.ToLower() && uio.Status.HasValue && uio.Status.Value == 1 && lst_orgs.Contains(uio.OrgId)
                            select uio.UserId).Distinct();

                return uios != null && uios.Count() > 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsUserInOrganization {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check is exist user in application
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool IsExistUser(string userName)
        {
            try
            {
                ////Check user is exist in any project
                //var findAnyProject = from uip in this.mdb.AHSUserInProjects
                //                     where uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() && uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == userName.ToLower() && uip.Status.HasValue && uip.Status.Value == 1
                //                     select uip;

                //bool isExist = (findAnyProject != null && findAnyProject.FirstOrDefault() != null);

                ////Check user is exist in any project via organization
                //if (!isExist)
                //{
                //    var findAnyProjectViaOrg = from oip in this.mdb.AHSOrganizationInProjects
                //                               join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                //                               where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uio.AHSAspnetUser.Username.ToLower() == userName.ToLower()) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue) && (uio.Status.Value == 1)
                //                               select oip;

                //    isExist = (findAnyProjectViaOrg != null && findAnyProjectViaOrg.FirstOrDefault() != null);
                //}

                // Check user is exist in application
                var findUser = from uia in this.mdb.AHSUserInApplications
                               where uia.AHSAspnetUser.Username.ToLower() == userName.ToLower() && uia.ApplicationName == this.ApplicationName
                               select uia;

                return findUser.Any();
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsExistuser error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check is exist user by email in application
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool IsExistUserByEmail(string email)
        {
            try
            {
                ////Check user is exist in any project
                //var findAnyProject = from uip in this.mdb.AHSUserInProjects
                //                     where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.AHSAspnetMembership_Userid.Email == email) && (uip.Status.HasValue) && (uip.Status.Value == 1)
                //                     select uip;

                //bool isExist = (findAnyProject != null && findAnyProject.FirstOrDefault() != null);

                ////Check user is exist in any project via organization
                //if (!isExist)
                //{
                //    var findAnyProjectViaOrg = from oip in this.mdb.AHSOrganizationInProjects
                //                               join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                //                               where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uio.AHSAspnetUser.AHSAspnetMembership.Email == email) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue) && (uio.Status.Value == 1)
                //                               select oip;

                //    isExist = (findAnyProjectViaOrg != null && findAnyProjectViaOrg.FirstOrDefault() != null);
                //}

                // Check user is exist in application
                var findUser = from uia in this.mdb.AHSUserInApplications
                               where uia.AHSAspnetUser.AHSAspnetMembership.Email.ToLower() == email.ToLower() &&
                                    uia.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                               select uia;


                return findUser.Any();
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsExistUserByEmail error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check is exist user in application
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool IsExistUser(Guid userID)
        {
            try
            {
                ////Check user is exist in any project
                //var findAnyProject = from uip in this.mdb.AHSUserInProjects
                //                     where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.AHSAspnetMembership_Userid.Userid == userID) && (uip.Status.HasValue && uip.Status.Value == 1)
                //                     select uip;

                //bool isExist = (findAnyProject != null && findAnyProject.FirstOrDefault() != null);

                ////Check user is exist in any project via organization
                //if (!isExist)
                //{
                //    var findAnyProjectViaOrg = from oip in this.mdb.AHSOrganizationInProjects
                //                               join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                //                               where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uio.AHSAspnetUser.Userid == userID) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue && uio.Status.Value == 1)
                //                               select oip;

                //    isExist = (findAnyProjectViaOrg != null && findAnyProjectViaOrg.FirstOrDefault() != null);
                //}

                // Check user is exist in application
                var findUser = from uia in this.mdb.AHSUserInApplications
                               where uia.UserID == userID && uia.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                               select uia;

                return findUser != null && findUser.FirstOrDefault() != null;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsExistUser error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check user is exist in role
        /// </summary>
        /// <returns></returns>
        public bool IsUserInRole(string userName, string roleName)
        {
            try
            {
                List<string> roles = new List<string>();

                //Check role user in project
                var uips = (from uip in this.mdb.AHSUserInProjects
                            where uip.Status.HasValue && uip.Status.Value == 1 && uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() && uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == userName.ToLower() && uip.Roleid.HasValue && uip.AHSAspnetRole.Rolename == roleName
                            select uip.AHSAspnetRole.Rolename).Distinct();

                foreach (var uip in uips)
                {
                    if (!roles.Contains(uip)) roles.Add(uip);
                }

                //Check role user in project via organization
                var oips = (from oip in this.mdb.AHSOrganizationInProjects
                            join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                            where oip.Status.HasValue && oip.Status.Value == 1 && uio.Status.HasValue && uio.Status.Value == 1
                                 && oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                 && uio.AHSAspnetUser.Username.ToLower() == userName.ToLower()
                                 && oip.Roleid.HasValue
                                 && oip.AHSAspnetRole.Rolename == roleName
                            select oip.AHSAspnetRole.Rolename).Distinct();

                foreach (var oip in oips)
                {
                    if (!roles.Contains(oip)) roles.Add(oip);
                }

                //Check role user in organ empowering
                var rios = (from rio in this.mdb.AHSUsersInOrganizations
                            where rio.Status.HasValue && rio.Status.Value == 1 && rio.AHSOrganization.OrgType == 1
                                 && rio.AHSOrganization.RoleID.HasValue && rio.AHSOrganization.AHSAspnetRole.Rolename == roleName && rio.AHSAspnetUser.Username.ToLower() == userName.ToLower()
                            select rio.AHSOrganization.AHSAspnetRole.Rolename).Distinct();

                foreach (var rio in rios)
                {
                    if (!roles.Contains(rio)) roles.Add(rio);
                }

                return roles.Count > 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsUserInRole {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check role is exist in user and project
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="userName"></param>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public bool IsRoleOfUserInProject(int projectId, string userName, string roleName)
        {
            try
            {
                bool bRet = false;

                //Check role user in project
                // Tạm thời : && (uip.AHSAspnetMembership_Userid.Isapproved.HasValue) && (uip.AHSAspnetMembership_UserInvite.Isapproved.Value == 1)
                var uips = (from uip in this.mdb.AHSUserInProjects
                            where (uip.Status.HasValue && uip.Status.Value == 1) && (uip.Projectid == projectId)
                                   && (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   && (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == userName.ToLower())
                                   && (uip.Roleid.HasValue) && (uip.AHSAspnetRole.Rolename == roleName)
                                   && (uip.AHSAspnetMembership_Userid.Islockedout.Value == 0)
                            select uip.AHSAspnetRole.Rolename).FirstOrDefault();

                if ((uips != null) && (uips.Any()))
                {
                    bRet = true;
                }
                else
                {
                    // Check role user in organization:
                    //Tạm thoi: uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.HasValue && uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.Value == 1 &&
                    var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                && (oip.Projectid == projectId) && (oip.Status.HasValue)
                                && (uio.AHSAspnetUser.Username.ToLower() == userName.ToLower())
                                && (oip.Status.Value == 1)
                                && (oip.AHSAspnetMembership.Islockedout.Value == 0 && oip.AHSAspnetRole.Rolename == roleName)
                                select oip).Distinct();

                    if ((oips != null) && (oips.Any()))
                    {
                        bRet = true;
                    }
                }

                return bRet;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsRoleOfUserInProject {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Remove users from roles for Application
        /// </summary>
        /// <param name="userNames"></param>
        /// <param name="roleNames"></param>
        /// <returns></returns>
        public bool RemoveUsersFromRoles(string[] userNames, string[] roleNames)
        {
            try
            {
                for (int i = 0; i < userNames.Length; i++)
                {
                    for (int j = 0; j < roleNames.Length; j++)
                    {
                        //Check role user in project
                        var uips = from uip in this.mdb.AHSUserInProjects
                                   where uip.Status.HasValue && uip.Status.Value == 1
                                   && uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                   && uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == userNames[i].ToLower()
                                   && uip.Roleid.HasValue && uip.AHSAspnetRole.Rolename == roleNames[j]
                                   select uip;

                        foreach (var it in uips)
                        {
                            it.Roleid = null;
                        }

                        //Check role user in project via organization
                        var oips = from oip in this.mdb.AHSOrganizationInProjects
                                   join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                   where oip.Status.HasValue && oip.Status.Value == 1 && uio.Status.HasValue && uio.Status.Value == 1
                                   && oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                   && uio.AHSAspnetUser.Username.ToLower() == userNames[i].ToLower()
                                   && oip.Roleid.HasValue
                                   && oip.AHSAspnetRole.Rolename == roleNames[j]
                                   select uio;

                        foreach (var it in oips)
                        {
                            it.Status = 0;
                        }

                        //Check role user in organ empowering
                        var rios = from rio in this.mdb.AHSUsersInOrganizations
                                   where rio.Status.HasValue && rio.Status.Value == 1 && rio.AHSOrganization.OrgType == 1
                                   && rio.AHSOrganization.RoleID.HasValue && rio.AHSOrganization.AHSAspnetRole.Rolename == roleNames[i]
                                   && rio.AHSAspnetUser.Username.ToLower() == userNames[j].ToLower()
                                   select rio;

                        foreach (var it in rios)
                        {
                            it.Status = 0;
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUsersFromRoles {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Add the exist user into application
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool AddUserToApplication(string userName)
        {
            try
            {
                MembershipUser mu = Membership.GetUser(userName);

                if (!this.IsExistUser(userName) && mu != null)
                {

                    var query = (from uia in this.mdb.AHSUserInApplications
                                 where (uia.UserID == Guid.Parse(mu.ProviderUserKey.ToString())) &&
                                 (uia.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select uia).FirstOrDefault();

                    if (query == null)
                    {
                        // If user is existing in AHS but not existing in Application
                        AHSUserInApplication uia = new AHSUserInApplication();

                        uia.UserID = new Guid(mu.ProviderUserKey.ToString());
                        uia.ApplicationName = this.ApplicationName;

                        this.mdb.AHSUserInApplications.InsertOnSubmit(uia);
                        this.mdb.SubmitChanges();
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Add the exist user into application by email
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool AddUserToApplicationByEmail(string userEmail)
        {
            try
            {
                string userName = Membership.GetUserNameByEmail(userEmail);
                MembershipUser mu = Membership.GetUser(userName);

                if (mu != null)
                {

                    var query = (from uia in this.mdb.AHSUserInApplications
                                 where (uia.UserID == Guid.Parse(mu.ProviderUserKey.ToString())) &&
                                 (uia.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select uia).FirstOrDefault();

                    if (query == null)
                    {
                        // If user is existing in AHS but not existing in Application
                        AHSUserInApplication uia = new AHSUserInApplication();

                        uia.UserID = new Guid(mu.ProviderUserKey.ToString());
                        uia.ApplicationName = this.ApplicationName;

                        this.mdb.AHSUserInApplications.InsertOnSubmit(uia);
                        this.mdb.SubmitChanges();
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToApplicationByEmail error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public bool AddUserToApplication(Guid userId)
        {
            try
            {
                MembershipUser mu = Membership.GetUser(userId);

                if (mu != null)
                {

                    var query = (from uia in this.mdb.AHSUserInApplications
                                 where (uia.UserID == userId) &&
                                 (uia.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select uia).FirstOrDefault();

                    if (query == null)
                    {
                        // If user is existing in AHS but not existing in Application
                        AHSUserInApplication uia = new AHSUserInApplication();

                        uia.UserID = userId;
                        uia.ApplicationName = this.ApplicationName;

                        this.mdb.AHSUserInApplications.InsertOnSubmit(uia);
                        this.mdb.SubmitChanges();
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Remove the exist user in application
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool RemoveUserFromApplication(string userName)
        {
            try
            {
                if (this.IsExistUser(userName))
                {
                    // If user is existing in Applicaton
                    var findUser = from user in this.mdb.AHSUserInApplications
                                   where user.ApplicationName == this.ApplicationName && user.AHSAspnetUser.Username.ToLower() == userName.ToLower()
                                   select user;

                    this.mdb.AHSUserInApplications.DeleteAllOnSubmit(findUser);
                    this.mdb.SubmitChanges();
                }

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUserFromApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Add User to project
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="projectID"></param>
        /// <returns></returns>
        /// Modify: Hoang Van Tai : Try Catch 
        public bool AddUserToProject(string userName, int projectID)
        {
            try
            {
                // Get userid
                var users = from user in this.mdb.AHSAspnetUsers
                            where user.Username.ToLower() == userName.ToLower()
                            select user;

                if (users != null && users.Any())
                {
                    // Get user
                    var userid = users.FirstOrDefault().Userid;

                    // Check project in Application
                    var pias = from pia in this.mdb.AHSMainProjects
                               where pia.AHSProjectType.ApplicationName.ToLower() == ApplicationName.ToLower() && pia.Id == projectID
                               select pia;

                    if (pias != null && pias.Any())
                    {
                        AHSUserInProject uip = null;

                        // Check user exist in project
                        var findUser = from fu in this.mdb.AHSUserInProjects
                                       where fu.Userid == userid && fu.Projectid == projectID
                                       select fu;

                        if (findUser == null || findUser.Any() == false)
                        {
                            // Not exist => add 
                            uip = new AHSUserInProject();

                            uip.Userid = userid;
                            uip.Projectid = projectID;
                            uip.Roleid = null;
                            uip.IsInvite = false;
                            uip.Status = 1;

                            this.mdb.AHSUserInProjects.InsertOnSubmit(uip);
                        }
                        else
                        {
                            uip = findUser.FirstOrDefault();
                            uip.Status = 1;
                        }

                        this.mdb.SubmitChanges();
                    }

                    // Add user into Application
                    this.AddUserToApplication(userName);

                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToProject error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Add User to project
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="projectID"></param>
        /// <returns></returns>
        /// Add: Hoang Van Tai  
        public bool AddUserToProject(string userName, int projectID, string roleName)
        {
            try
            {
                // Get userid
                var users = from user in this.mdb.AHSAspnetUsers
                            where user.Username.ToLower() == userName.ToLower()
                            select user;

                if (users != null && users.Any())
                {
                    // Get user
                    var userid = users.FirstOrDefault().Userid;

                    // Check project in Application
                    var pias = from pia in this.mdb.AHSMainProjects
                               where pia.AHSProjectType.ApplicationName.ToLower() == ApplicationName.ToLower() && pia.Id == projectID
                               select pia;

                    if (pias != null && pias.Any())
                    {
                        AHSUserInProject uip = null;

                        // Check user exist in project
                        var findUser = from fu in this.mdb.AHSUserInProjects
                                       where fu.Userid == userid && fu.Projectid == projectID
                                       select fu;

                        // Get role
                        var roleid = (from r in this.mdb.AHSAspnetRoles
                                      where (r.Rolename == roleName)
                                      select r.Roleid).FirstOrDefault();

                        if (findUser == null || findUser.Any() == false)
                        {
                            // Not exist => add 
                            uip = new AHSUserInProject();

                            uip.Userid = userid;
                            uip.Projectid = projectID;
                            uip.IsInvite = false;
                            uip.Status = 1;

                            if (roleid != null)
                            {
                                uip.Roleid = roleid;
                            }
                            else
                            {
                                uip.Roleid = null;
                            }

                            this.mdb.AHSUserInProjects.InsertOnSubmit(uip);
                        }
                        else
                        {
                            uip = findUser.FirstOrDefault();
                            uip.Status = 1;

                            if (roleid != null)
                            {
                                uip.Roleid = roleid;
                            }
                            else
                            {
                                uip.Roleid = null;
                            }
                        }

                        this.mdb.SubmitChanges();

                        // Add user into Application
                        this.AddUserToApplication(userName);
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToProject error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Invite User to the project
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="projectID"></param>
        /// <returns></returns>
        public int InviteUsersToProject(string[] userId, int projectID)
        {
            try
            {
                AHSUserInProject inviteUser = null;

                if (userId != null)
                {
                    for (int i = 0; i < userId.Length; i++)
                    {
                        Guid _userId = Guid.Parse(userId[i]);

                        var findUser = from uip in this.mdb.AHSUserInProjects
                                       where (uip.Userid == _userId) && (uip.Projectid == projectID) && (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                       select uip;

                        if (findUser == null || findUser.Any() == false)
                        {
                            // Not exist => add 
                            inviteUser = new AHSUserInProject();

                            inviteUser.Userid = _userId;
                            inviteUser.Projectid = projectID;
                            inviteUser.IsInvite = true;
                            inviteUser.Status = -1;
                            inviteUser.Roleid = null;

                            this.mdb.AHSUserInProjects.InsertOnSubmit(inviteUser);
                        }
                        else
                        {
                            inviteUser = findUser.FirstOrDefault();
                            inviteUser.Status = -1;
                            inviteUser.IsInvite = true;
                        }

                        this.mdb.SubmitChanges();
                    }
                }

                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.InviteUsersToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Accept or Invite User to the project
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="projectId"></param>
        /// <param name="isAccept"></param>
        /// <returns></returns>
        public int AcceptInvitedUserToProject(string userId, int projectId, bool isAccept)
        {
            try
            {
                AHSUserInProject inviteUser = null;
                var findUser = from uip in this.mdb.AHSUserInProjects
                               where (uip.Userid == Guid.Parse(userId)) && (uip.Projectid == projectId) && (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                               select uip;

                if (findUser == null || findUser.Any() == false)
                {
                    // if Accept then add user in the project
                    if (isAccept)
                    {
                        inviteUser = new AHSUserInProject();

                        inviteUser.Userid = Guid.Parse(userId);
                        inviteUser.Projectid = projectId;
                        inviteUser.IsInvite = (!isAccept);
                        inviteUser.Status = isAccept ? 1 : -1;
                        inviteUser.Roleid = null;

                        this.mdb.AHSUserInProjects.InsertOnSubmit(inviteUser);
                    }
                }
                else if (isAccept)
                {
                    inviteUser = findUser.FirstOrDefault();
                    inviteUser.IsInvite = (!isAccept);
                    inviteUser.Status = isAccept ? 1 : -1;
                }
                else if (!isAccept)
                {
                    this.mdb.AHSUserInProjects.DeleteAllOnSubmit(findUser);
                }

                this.mdb.SubmitChanges();
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AcceptInvitedUserToProject error {0}", ex);

                return -1;
            }

        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get User information for Permit user
        /// </summary>
        /// <param name="PermitName"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        /// Add:Hoang Van Tai
        /// Modify:Hoang Van Tai: Try Cacth
        public User GetUserInfo(string PermitName, string username)
        {
            try
            {
                OrganizationManager om = new OrganizationManager(this.ApplicationName);
                ProjectManager pm = new ProjectManager(this.ApplicationName);
                User ret = null;

                var user = (from uip in this.mdb.AHSUserInProjects
                            where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == PermitName.ToLower()) && (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower() || uip.AHSAspnetMembership_Userid.Email.ToLower() == username.ToLower())
                            && uip.AHSAspnetRole.Adminforprojectype.HasValue && uip.AHSAspnetRole.AHSProjectType_Adminforprojectype.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                            select new { userid = uip.Userid, username = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username, email = uip.AHSAspnetMembership_UserInvite.Email, IsPermitUser = uip.AHSAspnetRole.Isrolepermit }).FirstOrDefault();

                if (user != null)
                {
                    ret = new User();

                    ret.UserId = user.userid;
                    ret.UserName = user.username;
                    ret.Email = user.email;

                    ProfileBase pb = ProfileBase.Create(user.username);
                    var phone = pb.GetPropertyValue("Phone");

                    if (phone != null)
                        ret.Phone = phone.ToString();
                    else
                        ret.Phone = "";

                    ret.ApplicationName = PermitName;
                    ret.Orgs = om.GetOrganizationIdForUser(user.userid);
                    ret.Projects = pm.GetProjectIdForUser(user.userid);

                    //ret.IsPermitUser = user.IsPermitUser == null ? false : user.IsPermitUser.Value;
                    ret.IsPermitUser = (username.ToLower() == "sa");
                }
                else
                {
                    ret = this.GetUserInfo(username);
                    ret.IsPermitUser = (username.ToLower() == "sa");
                    
                }
                

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserInfo error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get User information for any user 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        /// Add:Hoang Van Tai
        /// Modify:Hoang Van Tai Try Catch 
        public User GetUserInfo(string username)
        {
            try
            {
                OrganizationManager om = new OrganizationManager(this.ApplicationName);
                ProjectManager pm = new ProjectManager(this.ApplicationName);
                User ret = null;

                var user = (from uia in this.mdb.AHSUserInApplications
                            where uia.AHSAspnetUser.Username.ToLower() == username.ToLower()
                            select new { userid = uia.UserID, username = uia.AHSAspnetUser.Username, email = uia.AHSAspnetUser.AHSAspnetMembership.Email }).FirstOrDefault();

                if (user != null)
                {
                    ret = new User();

                    ret.UserId = user.userid;
                    ret.UserName = user.username;
                    ret.Email = user.email;

                    ProfileBase pb = ProfileBase.Create(user.username);
                    var phone = pb.GetPropertyValue("Phone");

                    if (phone != null)
                        ret.Phone = phone.ToString();
                    else
                        ret.Phone = "";

                    ret.ApplicationName = this.ApplicationName;
                    ret.Orgs = om.GetOrganizationIdForUser(user.userid);
                    ret.Projects = pm.GetProjectIdForUser(user.userid);
                    ret.IsPermitUser = false;
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserInfo error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Check User isExits in the AHS, input username is username or email  
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public bool IsExistUserInAHS(string username)
        {
            try
            {
                // Get userid in AHSAspnetUsers where  Username or Email
                var user = (from u in this.mdb.AHSAspnetUsers
                            where (u.Username.ToLower() == username.ToLower()) || (u.AHSAspnetMembership.Email.ToLower() == username.ToLower())
                            select u.Userid);

                return (user != null && user.Any());
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.IsExistUserInAHS error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Get MembershipUser
        /// </summary>
        /// <returns></returns>
        public MembershipUser GetUser(string username, bool userIsOnline)
        {
            try
            {
                MembershipUser retVal = null;

                if (this.IsExistUser(username)) retVal = Membership.GetUser(username);

                return retVal;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the user list in project
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="projectid"></param>
        /// <returns></returns>
        public Dictionary<Guid, string> GetUserInProject(int projectid)
        {
            try
            {
                Dictionary<Guid, string> retLst = new Dictionary<Guid, string>();

                // Get user in project
                var uips = (from uip in this.mdb.AHSUserInProjects
                            where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.Projectid == projectid) && (uip.Status.HasValue) && (uip.Status.Value == 1) && (uip.AHSAspnetMembership_Userid.Isapproved.HasValue && uip.AHSAspnetMembership_Userid.Isapproved.Value == 1 && uip.AHSAspnetMembership_Userid.Islockedout.Value == 0)
                            select new { userid = uip.AHSAspnetMembership_Userid.Userid, username = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username }).Distinct();

                foreach (var uip in uips)
                {
                    retLst.Add(uip.userid, uip.username);
                }

                // Get user in project via organization
                var oips = (from oip in this.mdb.AHSOrganizationInProjects
                            join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                            where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue) && (uio.Status.Value == 1) && (oip.Projectid == projectid) && (uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.HasValue && uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.Value == 1 && uio.AHSAspnetUser.AHSAspnetMembership.Islockedout.Value == 0)
                            select new { userid = uio.AHSAspnetUser.Userid, username = uio.AHSAspnetUser.Username }).Distinct();

                foreach (var oip in oips)
                {
                    if (!retLst.ContainsKey(oip.userid)) retLst.Add(oip.userid, oip.username);
                }

                return retLst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserInProject error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Le Anh Phong
        /// Get the user list is exist in Project not via Organization
        /// Project Request: CS
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="projectid"></param>
        /// <returns></returns>
        /// Modify:Hoang Van Tai
        public Dictionary<Guid, User> GetListUserInProject(int projectid)
        {
            try
            {
                Dictionary<Guid, User> list = new Dictionary<Guid, User>();

                var uips = (from uip in this.mdb.AHSUserInProjects
                            where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.Projectid == projectid) && (uip.Status.HasValue) && (uip.Status.Value == 1) && (uip.AHSAspnetMembership_Userid.Isapproved.HasValue && uip.AHSAspnetMembership_Userid.Isapproved.Value == 1 && uip.AHSAspnetMembership_Userid.Islockedout.Value == 0)
                            select new { userid = uip.AHSAspnetMembership_Userid.Userid, username = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username, Email = uip.AHSAspnetMembership_Userid.Email, RoleId = uip.Roleid, RoleName = uip.AHSAspnetRole.Rolename }).Distinct();

                foreach (var uip in uips)
                {
                    AHSModel.User _user = new User();
                    _user.UserId = uip.userid;
                    _user.UserName = uip.username;
                    _user.Email = uip.Email;
                    _user.RoleId = uip.RoleId;
                    _user.RoleName = uip.RoleName;

                    ProfileBase pb = ProfileBase.Create(uip.username);

                    var phone = pb.GetPropertyValue("Phone");

                    if (phone != null)
                        _user.Phone = phone.ToString();
                    else
                        _user.Phone = "";

                    var name = pb.GetPropertyValue("Name");

                    if (name != null)
                        _user.Name = name.ToString();
                    else
                        _user.Name = "";

                    list.Add(_user.UserId, _user);
                }

                return list;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListUserInProject error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="projectid"></param>
        /// <returns></returns>
        public List<User> GetWaitingAcceptUserForProject(int projectid)
        {
            try
            {
                List<User> list = new List<User>();

                var uips = (from uip in this.mdb.AHSUserInProjects
                            where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                 (uip.Projectid == projectid) && (uip.Status.HasValue) && (uip.Status.Value == -1) &&
                                 (uip.AHSAspnetMembership_Userid.Isapproved.HasValue && uip.AHSAspnetMembership_Userid.Isapproved.Value == 1 && uip.AHSAspnetMembership_Userid.Islockedout.Value == 0)
                            select new { userid = uip.AHSAspnetMembership_Userid.Userid, username = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username, Email = uip.AHSAspnetMembership_Userid.Email, RoleId = uip.Roleid, RoleName = uip.AHSAspnetRole.Rolename }).Distinct();

                foreach (var uip in uips)
                {
                    AHSModel.User _user = new User();
                    _user.UserId = uip.userid;
                    _user.UserName = uip.username;
                    _user.Email = uip.Email;
                    _user.RoleId = uip.RoleId;
                    _user.RoleName = uip.RoleName;

                    ProfileBase pb = ProfileBase.Create(uip.username);

                    var phone = pb.GetPropertyValue("Phone");

                    if (phone != null)
                        _user.Phone = phone.ToString();
                    else
                        _user.Phone = "";

                    var name = pb.GetPropertyValue("Name");

                    if (name != null)
                        _user.Name = name.ToString();
                    else
                        _user.Name = "";

                    list.Add(_user);
                }

                return list;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetWaitingAcceptUserForProject error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the list user in organization for the application and OrgId
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="OrgId"></param>
        /// <returns></returns>
        public Dictionary<Guid, MembershipUser> GetUserInOrganization(Guid OrgId)
        {
            try
            {
                Dictionary<Guid, MembershipUser> lst = new Dictionary<Guid, MembershipUser>();

                List<string> uip = (new Common(this.ApplicationName)).GetListUserNameInApplication();

                var users = (from user in this.mdb.AHSUsersInOrganizations
                             where (user.OrgId == OrgId) && (user.AHSAspnetUser.AHSAspnetMembership.Islockedout.Value == 0)
                             select new { UserId = user.UserId, Username = user.AHSAspnetUser.Username }).Distinct();

                foreach (var user in users)
                {
                    if (!lst.ContainsKey(user.UserId) && uip.Contains(user.Username.ToLower()))
                    {
                        lst.Add(user.UserId, Membership.GetUser(user.Username));
                    }
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserInOrganization error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the User into the Organization
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="idOrgs"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool AddUserToOrgs(Guid UserID, string[] idOrgs, ref string msg)
        {
            try
            {
                for (int i = 0; i < idOrgs.Length; i++)
                {
                    Guid OrgID = Guid.Empty;

                    if (Guid.TryParse(idOrgs[i], out OrgID) && OrgID != Guid.Empty)
                    {
                        AHSUsersInOrganization entity = new AHSUsersInOrganization();

                        entity.UserId = UserID;
                        entity.OrgId = OrgID;
                        entity.IsInvite = false;
                        entity.Status = 1;

                        this.mdb.AHSUsersInOrganizations.InsertOnSubmit(entity);

                    }
                }

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                msg = ex.Message;

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToOrgs error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="userInviteID"></param>
        /// <param name="idOrgs"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public int AddOrgsToUser(Guid userId, string userInviteID, string[] idOrgs, ref string msgError)
        {
            try
            {
                //OrganizationManager om = new OrganizationManager();
                //UserManager um = new UserManager();
                foreach (var idOrg in idOrgs)
                {
                    var _idOrg = idOrg;

                    

                    int index = idOrg.LastIndexOf("[");
                    if (index != -1)
                    {
                        _idOrg = idOrg.Substring(0, index);
                    }

                    var csuserinorg = new AHSDbContext.AHSUsersInOrganization();
                    csuserinorg.UserId = userId;
                    csuserinorg.OrgId = Guid.Parse(_idOrg); //idOrg
                    csuserinorg.IsInvite = false;

                    csuserinorg.UserInvite = Guid.Parse(userInviteID); ;

                    csuserinorg.Status = 1; // Assign

                    // 
                    //csuserinorg.RoleId = RoleId 


                    this.mdb.AHSUsersInOrganizations.InsertOnSubmit(csuserinorg);

                    // Thamm thoi khong co trong phan tich hop CS
                    //om.AddKnown(csuserinorg.UserId, csuserinorg.OrgId);
                    //um.AddKnown(csuserinorg.UserId, csuserinorg.UserInvite.Value);

                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddOrgsToUser error {0}", ex);
                msgError = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the user into list project
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="idProjs"></param>
        /// <returns></returns>
        public bool AddUserToProjects(Guid UserID, string[] idProjs)
        {
            try
            {
                for (int i = 0; i < idProjs.Length; i++)
                {
                    if (!string.IsNullOrEmpty(idProjs[i]))
                    {
                        string[] idProj = idProjs[i].Split('^');
                        int ProjectID = 0;
                        Guid RoleID = Guid.Empty;

                        if (Int32.TryParse(idProj[0], out ProjectID) && ProjectID != 0 && Guid.TryParse(idProj[1], out RoleID))
                        {
                            AHSUserInProject entity = new AHSUserInProject();

                            entity.Userid = UserID;
                            entity.Projectid = ProjectID;
                            entity.IsInvite = false;
                            entity.Status = 1;
                            entity.Roleid = null;

                            if (RoleID != Guid.Empty) entity.Roleid = RoleID;

                            this.mdb.AHSUserInProjects.InsertOnSubmit(entity);
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToProjects error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the user into list project with userInviteID
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="userInviteID"></param>
        /// <param name="idPrjRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int AddUserToProjects(Guid userId, string userInviteID, string[] idPrjRoles, ref string message)
        {
            try
            {

                foreach (var idPrjRole in idPrjRoles)
                {
                    string[] arrPrjRole = idPrjRole.Split('^');
                    int prjId = int.Parse(arrPrjRole[0]);
                    //int isApproved = int.Parse(arrPrjRole[1]);
                    Guid roleId = Guid.Parse(arrPrjRole[1]);

                    var userrole = from uip in this.mdb.AHSUserInProjects
                                   where ((uip.Userid == userId) && (uip.Projectid == prjId)) &&
                                         (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   select uip;

                    var csuserinprj = new AHSDbContext.AHSUserInProject();
                    if (!userrole.Any())
                    {
                        csuserinprj.Projectid = prjId;
                        csuserinprj.Userid = userId;
                        csuserinprj.UserInvite = Guid.Parse(userInviteID);

                        csuserinprj.IsInvite = false;
                        csuserinprj.Status = 1;

                        if (arrPrjRole[1].ToString() != "00000000-0000-0000-0000-000000000000")
                        {
                            csuserinprj.Roleid = Guid.Parse(arrPrjRole[1]);
                        }
                        else
                        {
                            csuserinprj.Roleid = null;
                        }

                        this.mdb.AHSUserInProjects.InsertOnSubmit(csuserinprj);

                        // Hiện tại bên CS chưa có phần Known
                        //MainProjectManager pm = new MainProjectManager();
                        //pm.AddKnown(csuserinprj.Userid, csuserinprj.Projectid, false);
                    }
                    else
                    { //else if ((arrPrjRole[2].ToString() != "00000000-0000-0000-0000-000000000000") && (arrPrjRole[2].ToString() != "undefined"))
                        csuserinprj = userrole.FirstOrDefault();
                        csuserinprj.Projectid = prjId;
                        csuserinprj.Userid = userId;
                        csuserinprj.UserInvite = Guid.Parse(userInviteID);
                        csuserinprj.IsInvite = false;
                        csuserinprj.Status = 1;

                        if ((arrPrjRole[1].ToString() != "00000000-0000-0000-0000-000000000000") && (arrPrjRole[1].ToString() != "undefined"))
                        {
                            csuserinprj.Roleid = Guid.Parse(arrPrjRole[1]);
                        }
                        else
                        {
                            csuserinprj.Roleid = null;
                        }
                    }

                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToProjects error {0}", ex);
                message = ex.Message;

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the user from the all project for application
        /// </summary>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public bool RemoveUserFromProjects(Guid UserID)
        {
            try
            {
                var prjs = from prj in this.mdb.AHSUserInProjects
                           where (prj.Userid == UserID) && (prj.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select prj;

                this.mdb.AHSUserInProjects.DeleteAllOnSubmit(prjs);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] RemoveUserFromProjects error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove user from project
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="username"></param>
        /// <param name="rolename"></param>
        /// <returns></returns>
        public bool RemoveUserFromProjects(int projectId, string username, string rolename = null)
        {
            try
            {
                Guid userID = Guid.Parse(Membership.GetUser(username).ProviderUserKey.ToString());

                if (rolename != null)
                {
                    // Remove user in project for Role
                    var upr = from prj in this.mdb.AHSUserInProjects
                              where ((prj.Userid == userID) && (prj.Projectid == projectId) && (prj.AHSAspnetRole.Rolename == rolename))
                              select prj;
                    this.mdb.AHSUserInProjects.DeleteAllOnSubmit(upr);
                }
                else
                {
                    // Not role
                    var uip = from prj in this.mdb.AHSUserInProjects
                              where ((prj.Userid == userID) && (prj.Projectid == projectId))
                              select prj;
                    this.mdb.AHSUserInProjects.DeleteAllOnSubmit(uip);
                }

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] RemoveUserFromProjects error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the user from the project for application and  not application default
        /// </summary>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public bool RemoveUserFromProjectsForApplication(Guid UserID)
        {
            try
            {
                var prjs = from prj in this.mdb.AHSUserInProjects
                           where (prj.Userid == UserID) && (prj.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select prj;

                this.mdb.AHSUserInProjects.DeleteAllOnSubmit(prjs);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUserFromProjectsForApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove Org from User
        /// </summary>
        /// <param name="idOrgDels"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public int RemoveOrgsFromUser(string[] idOrgDels, Guid userId)
        { // Remove  Org from User 
            try
            {

                foreach (var item in idOrgDels)
                {
                    Int32 Num;
                    bool isNum = Int32.TryParse(item, out Num);

                    if (!isNum)
                    {
                        var deleteds = from uio in this.mdb.AHSUsersInOrganizations
                                       join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals (oip.Orgid)
                                       where (uio.OrgId == Guid.Parse(item)) && (uio.UserId == userId) &&
                                            (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                       select uio;

                        this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(deleteds);
                    }

                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveOrgsFromUser error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove Project from User 
        /// </summary>
        /// <param name="idPrjDels"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public int RemoveProjectsFromUser(string[] idPrjDels, Guid userId)
        {
            try
            {
                foreach (var item in idPrjDels)
                {
                    Int32 Num;
                    bool isNum = Int32.TryParse(item, out Num);
                    if (isNum)
                    {
                        var deleteds = from uip in this.mdb.AHSUserInProjects
                                       where (uip.Projectid == Num) && (uip.Userid == userId) &&
                                             (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                       select uip;

                        this.mdb.AHSUserInProjects.DeleteAllOnSubmit(deleteds);
                    }
                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveProjectsFromUser error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the user from the organization for UserID, ApplicationName  
        /// </summary>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public bool RemoveUserFromOrgs(Guid UserID)
        {
            try
            {
                var orgs = from org in this.mdb.AHSUsersInOrganizations
                           join oip in this.mdb.AHSOrganizationInProjects on org.OrgId equals (oip.Orgid)
                           where (org.UserId == UserID) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select org;

                this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(orgs);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUserFromOrgs error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove User in Prj is delete 
        /// </summary>
        /// <param name="idUserDels"></param>
        /// <param name="idPrj"></param>
        /// <returns></returns>
        public int RemoveUsersFromProject(string[] idUserDels, int idPrj)
        {
            try
            {
                foreach (var item in idUserDels)
                {
                    Guid uUserid;
                    string[] userid = item.Split('^');


                    if (Guid.TryParse(userid[0], out  uUserid))
                    {

                        var deleteds = from uip in this.mdb.AHSUserInProjects
                                       where (uip.Projectid == idPrj) && (uip.Userid == Guid.Parse(userid[0]))
                                       select uip;

                        this.mdb.AHSUserInProjects.DeleteAllOnSubmit(deleteds);


                        var query = from iv in this.mdb.AHSInviteEmails
                                    where ((iv.PrjID == idPrj) && (iv.Code == Guid.Parse(userid[0])))
                                    select iv;

                        this.mdb.AHSInviteEmails.DeleteAllOnSubmit(query);
                    }
                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUsersFromProject error {0}", ex);

                return -1;
            }


        }

        /// <summary>
        /// Author:Hoang Van Tai 
        /// Remove the user into the organization for Application and not Application  default
        /// </summary>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public bool RemoveUserFromOrgsForApplication(Guid UserID)
        {
            try
            {
                var orgs = from org in this.mdb.AHSUsersInOrganizations
                           where (org.UserId == UserID) && (org.AHSOrganization.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select org;

                this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(orgs);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUserFromOrgsForApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Reomve the user into list idPrjDels for CS
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="idPrjDels"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool RemoveUserFromProjectsForApplication(Guid UserID, Int32[] idPrjDels, ref string message)
        {
            try
            {
                // If idPrjDels is not null  
                if (idPrjDels != null)
                {
                    foreach (var item in idPrjDels)
                    {
                        if (item != 0)
                        {
                            var deleteds = from prj in this.mdb.AHSUserInProjects
                                           where ((prj.Userid == UserID) && (prj.Projectid == item)) && prj.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                           select prj;

                            this.mdb.AHSUserInProjects.DeleteAllOnSubmit(deleteds);
                        }
                    }

                    this.mdb.SubmitChanges();
                }

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUserFromProjectsForApplication error {0}", ex);

                message = ex.Message;

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the user from list idOrgDels for Application
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="idOrgDels"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool RemoveUserFromOrgsForApplication(Guid UserID, string[] idOrgDels, ref string message)
        {
            try
            {
                // If idOrgDels is not null  
                if (idOrgDels != null)
                {
                    foreach (var item in idOrgDels)
                    {
                        Guid OranizationId;
                        bool isNum = Guid.TryParse(item, out OranizationId);

                        if (isNum)
                        {
                            var deleteds = from org in this.mdb.AHSUsersInOrganizations
                                           join uip in this.mdb.AHSOrganizationInProjects on org.OrgId equals uip.Orgid
                                           where ((org.UserId == UserID) && (org.OrgId == OranizationId) &&
                                                 (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()))
                                           select org;

                            this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(deleteds);
                        }
                    }

                    this.mdb.SubmitChanges();
                }

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.RemoveUserFromOrgsForApplication error {0}", ex);

                message = ex.Message;

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the user name in role for project
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="projectid"></param>
        /// <param name="rolename"></param>
        /// <returns></returns>
        /// 
        public string[] GetUserInRole(int projectid, string rolename, bool include_via_org = true)
        {
            try
            {
                List<string> users = new List<string>();

                // Get user name in project
                var uips = (from uip in this.mdb.AHSUserInProjects
                            where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.Projectid == projectid) && (uip.Status.HasValue) && (uip.Status.Value == 1) && (uip.AHSAspnetMembership_Userid.Isapproved.HasValue && uip.AHSAspnetMembership_Userid.Isapproved.Value == 1 && uip.AHSAspnetMembership_Userid.Islockedout.Value == 0 && uip.AHSAspnetRole.Rolename == rolename)
                            select new { username = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username }).Distinct();

                foreach (var item in uips)
                {
                    users.Add(item.username);
                }

                //If include_via_org = true then Get user name in organization
                if (include_via_org)
                {
                    // Get user name in organization
                    var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (oip.Projectid == projectid) && (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.HasValue && uio.AHSAspnetUser.AHSAspnetMembership.Isapproved.Value == 1 && uio.AHSAspnetUser.AHSAspnetMembership.Islockedout.Value == 0 && oip.AHSAspnetRole.Rolename == rolename)
                                select new { username = uio.AHSAspnetUser.Username }).Distinct();

                    foreach (var item in oips)
                    {
                        users.Add(item.username);
                    }
                }

                return users.ToArray(); ;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserInRole error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Insert Invite email Org
        /// </summary>
        /// <param name="emails"></param>
        /// <param name="OrgId"></param>
        /// <param name="RoleId"></param>
        /// <returns></returns>
        public string InsertInviteEmailOrg(string emails, Guid OrgId, Guid? RoleId)
        {
            try
            {
                AHSInviteEmail invite = new AHSInviteEmail();
                invite.Email = emails;
                invite.Code = Guid.NewGuid();
                invite.OrgID = OrgId;

                if ((RoleId.HasValue) && (RoleId.ToString() != "00000000-0000-0000-0000-000000000000"))
                {
                    invite.RoleID = RoleId;
                }
                else
                {
                    invite.RoleID = null;
                }

                this.mdb.AHSInviteEmails.InsertOnSubmit(invite);
                this.mdb.SubmitChanges();

                return invite.Code.ToString();
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.InsertInviteEmailOrg error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="emails"></param>
        /// <param name="RoleId"></param>
        /// <returns></returns>
        public string InsertInvite(string emails, Guid? RoleId, Guid? OwnerID)
        {
            try
            {
                AHSInviteEmail invite = new AHSInviteEmail();
                invite.Email = emails;
                invite.Code = Guid.NewGuid();
                invite.OwnerID = OwnerID;

                if ((RoleId.HasValue) && (RoleId.ToString() != "00000000-0000-0000-0000-000000000000"))
                    invite.RoleID = RoleId;
                else
                {
                    invite.RoleID = null;
                }

                this.mdb.AHSInviteEmails.InsertOnSubmit(invite);
                this.mdb.SubmitChanges();

                return invite.Code.ToString();
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.InsertInvite error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Send email
        /// </summary>
        /// <param name="email"></param>
        /// <param name="code"></param>
        /// <param name="message"></param>
        public void SendEmail(string email, Guid code, ref string message)
        {
            try
            {
                ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                string root = alm.GetLinkByApplication();

                var activeLink = String.Format(@" <a href='" + root + "Account/Register?codes=" + code + "'>here</a> ");
                var cs4 = String.Format(@" <a href='" + root + "'>Collaboration System</a>");
                string body = String.Format(@"Click" + activeLink + "to register your account to " + cs4);

                message = String.Empty;

                NotificationUtils.SendMail("CS Admin", email, "Invite", body, MailType.ExternalNotification);

            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.SendEmail error {0}", ex);
            }

        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get list user from Org 
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public List<User> GetUsersListFromOrg(string orgId, ref string msgError)
        {
            try
            {
                List<User> ret = new List<User>();

                Guid _orgId;
                if (!Guid.TryParse(orgId, out _orgId))
                    return null;

                // User in Organization
                var query = (from u in this.mdb.AHSAspnetUsers
                             join uig in this.mdb.AHSUsersInOrganizations on u.Userid equals uig.UserId
                             join oip in this.mdb.AHSOrganizationInProjects on uig.OrgId equals oip.Orgid
                             orderby u.Username
                             where (uig.OrgId == _orgId) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                             select new { UserId = u.Userid, UserName = u.Username, Type = uig.IsInvite, TT = uig.Status, RoleId = uig.RoleId }).Distinct();

                foreach (var _user in query)
                {
                    User user;
                    user = new User();
                    user.UserId = _user.UserId;
                    user.UserName = _user.UserName;
                    user.TypeUser = _user.Type.HasValue ? (_user.Type.Value ? 1 : 0) : 0;  // assign:0; Invite:1
                    user.RoleId = _user.RoleId;


                    if ((user.TypeUser == 1) && (_user.TT != null))
                    {
                        switch (_user.TT)
                        {
                            case -1:
                                {
                                    // Nothing
                                    break;
                                }
                            case 0:
                                {
                                    // Reject
                                    user.TypeUser = 10;
                                    break;
                                }
                            case 1:
                                {
                                    // Accept
                                    user.TypeUser = 11;
                                    break;
                                }

                        }
                    }
                    if (_user.TT == 1)
                    {
                        user.TypeUser = 0; // assign 
                    }
                    else if (_user.TT == 0)
                    {
                        user.TypeUser = -1;
                    }

                    if (_user.TT != null)
                        user.StatusInOrgan = _user.TT.Value;
                    else
                        user.StatusInOrgan = -3;
                    ret.Add(user);
                    user = null;
                }


                //InviteEmail

                // User in Organization
                var InviteEmail = (from u in this.mdb.AHSInviteEmails
                                   join org in this.mdb.AHSOrganizations on u.OrgID equals org.Id
                                   join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                                   orderby u.Email
                                   where (org.Id == _orgId) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   select new { UserId = u.Code, UserName = u.Email }).Distinct();


                foreach (var item in InviteEmail)
                {
                    User user;
                    user = new User();
                    user.UserId = item.UserId;
                    user.UserName = item.UserName;
                    user.TypeUser = 1;
                    user.StatusInOrgan = -2;
                    ret.Add(user);
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUsersListFromOrg error {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public List<User> GetUserListBySA(string keyword, ref string msgError)
        {
            try
            {
                List<User> ret = new List<User>();

                var users = (from ms in this.mdb.AHSAspnetMemberships
                             join us in this.mdb.AHSAspnetUsers on ms.Userid equals us.Userid
                             where ((ms.Email.ToLower().Contains(keyword) || us.Username.ToLower().Contains(keyword))) &&
                                   (us.Username.ToLower() == "sa")
                             select new { userid = us.Userid, username = us.Username, email = ms.Email, isapproved = ms.Isapproved, isLockedout = ms.Islockedout, ownerid = ms.Ownerid, ownerisuser = ms.Ownerisuser }).
                            Union(from ms in this.mdb.AHSAspnetMemberships
                                  join us in this.mdb.AHSAspnetUsers on ms.Userid equals us.Userid
                                  join uip in this.mdb.AHSUserInProjects on ms.Userid equals uip.Userid
                                  where ((ms.Email.ToLower().Contains(keyword) || us.Username.ToLower().Contains(keyword))) &&
                                        (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                  orderby (us.Username)
                                  select new { userid = us.Userid, username = us.Username, email = ms.Email, isapproved = ms.Isapproved, isLockedout = ms.Islockedout, ownerid = ms.Ownerid, ownerisuser = ms.Ownerisuser }).Distinct();

                if (users == null)
                {
                    return null;
                }


                foreach (var user in users)
                {
                    var obj = new User();

                    obj.UserName = user.username;
                    obj.Email = user.email;
                    obj.UserId = user.userid;
                    if (user.isapproved.HasValue)
                    {
                        obj.IsApproved = user.isapproved.Value == 1 ? true : false;
                    }
                    else
                    {
                        obj.IsApproved = false;
                    }

                    // Locked
                    if (user.isLockedout.HasValue)
                    {
                        obj.IsApproved = user.isLockedout.Value == 0 ? true : false;
                    }

                    ProfileBase pb = ProfileBase.Create(user.username);
                    var phone = pb.GetPropertyValue("Phone");
                    if (phone != null)
                        obj.Phone = phone.ToString();
                    else
                        obj.Phone = "";

                    var name = pb.GetPropertyValue("Name");
                    if (name != null)
                        obj.Name = name.ToString();
                    else
                        obj.Name = "";

                    ret.Add(obj);
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserListBySA error {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Set properties Approved and UnlockUser for user
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="isApproved"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public int SetApproved(Guid userId, bool isApproved, ref string msgError)
        {
            try
            {
                MembershipUser mu = Membership.GetUser(userId);
                mu.IsApproved = isApproved;
                Membership.UpdateUser(mu);

                if (mu.IsApproved)
                {
                    mu.UnlockUser();
                }

                return 0;
            }

            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.SetApproved error {0}", ex);
                msgError = ex.Message;

                return -1;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public User GetUserOwnerByPrimaryKey(string userId, ref string msgError)
        {
            try
            {
                User ret = new User();
                var query = (from u in this.mdb.AHSAspnetMemberships
                             where (u.Userid == Guid.Parse(userId))
                             select new { UserId = u.Userid, Ownerid = u.Ownerid, Ownerisuser = u.Ownerisuser }).FirstOrDefault();

                if (query != null)
                {
                    ret.UserId = query.UserId;
                    ret.OwnerID = query.Ownerid;
                    ret.OwnerIsUser = query.Ownerisuser;
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUserOwnerByPrimaryKey error {0}", ex);
                msgError = ex.Message;

                return null;
            }


        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Set Owner 
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="ownerid"></param>
        /// <param name="ownerisUser"></param>
        /// <returns></returns>
        public bool SetOwner(string userId, string ownerid, bool ownerisUser)
        {
            try
            {
                Guid uidId = Guid.Parse(userId);

                // Owner not User (Owner is Organization)
                if (!ownerisUser)
                {
                    _SetOwnerAspnet_MembershipByOrganization(userId, ownerid);
                }
                else
                {
                    var _user = this.mdb.AHSAspnetMemberships.Where(m => m.Userid == uidId).FirstOrDefault();
                    _user.Ownerid = Guid.Parse(ownerid);
                    _user.Ownerisuser = ownerisUser;
                    this.mdb.SubmitChanges();

                    //Add known: Hiện tại trong CS chưa có known
                    //AddKnown(_user.Ownerid.Value, uidId);
                }

            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.SetOwner error {0}", ex);

                return false;
            }

            return true;

        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add user for SA
        /// </summary>
        /// <param name="user"></param>
        /// <param name="username"></param>
        /// <param name="name"></param>
        /// <param name="email"></param>
        /// <param name="phone"></param>
        /// <param name="password"></param>
        /// <param name="ownerid"></param>
        /// <param name="isApproved"></param>
        /// <param name="isSendEmail"></param>
        /// <param name="idOrgs"></param>
        /// <param name="idPrjRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public Guid? AddUser(string user, string username, string name, string email, string phone, string password, string ownerid, string isApproved, string isSendEmail, string[] idOrgs, string[] idPrjRoles, ref string msgError)
        {
            try
            {
                bool _isApproved = isApproved.ToLower() == "true" ? true : false;
                bool ownerisUser = true;

                if (password == null)
                {
                    password = Membership.GeneratePassword(6, 2);
                    while (password.IndexOf('{') != -1 || password.IndexOf('}') != -1) password = Membership.GeneratePassword(6, 2);
                }

                MembershipCreateStatus status;
                Membership.CreateUser(username, password, email, null, null, _isApproved, null, out status);

                if (status == MembershipCreateStatus.Success)
                {
                    UserManager um = new UserManager(this.ApplicationName);

                    //Check the exist user
                    MembershipUser mu = Membership.GetUser(username);

                    if ((this.ApplicationName != "AHS") && (idPrjRoles == null))
                    {
                        //Add user into Empowering organization CS
                        var findOrg = (from orgs in this.mdb.AHSOrganizationEmpowerForApps
                                       where orgs.ApplicationName == this.ApplicationName
                                       select orgs.OrganID).Distinct();

                        if (findOrg != null && findOrg.Count() > 0)
                        {
                            var org = findOrg.FirstOrDefault();

                            if (org != null && !um.IsUserInOrganizationOutside(username, org))
                            {
                                //Add user to organization
                                AHSUsersInOrganization uio = new AHSUsersInOrganization();

                                uio.OrgId = org;
                                uio.UserId = Guid.Parse(mu.ProviderUserKey.ToString());
                                uio.IsInvite = false;
                                uio.Status = 1;

                                this.mdb.AHSUsersInOrganizations.InsertOnSubmit(uio);

                                this.mdb.SubmitChanges();
                            }
                        }
                    }

                    // Add user into Application
                    this.AddUserToApplication(username);

                    MembershipUser newUser = Membership.GetUser(username);

                    Guid uId = (Guid)newUser.ProviderUserKey;

                    //Send email
                    if (isSendEmail.ToLower() == "true")
                    {
                        ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                        string root = alm.GetLinkByApplication();

                        var cs4 = String.Format(@" <a href='" + root + "'>Collaboration System</a>");
                        string body = String.Format(@"Hi,<br/>You are now member of " + cs4 + " with<br/>User name: " + newUser.UserName + "<br/>Password: " + password);

                        NotificationUtils.SendMail("CS Admin", newUser.Email, "Member Account", body, MailType.ExternalNotification);

                    }

                    //Save profile
                    ProfileBase pb = ProfileBase.Create(username);
                    pb.SetPropertyValue("Phone", phone);
                    pb.SetPropertyValue("Name", name);
                    pb.Save();

                    // Set Ower to User

                    // if ownerid is UserId  the ownerisUser = true; then ownerisUser = false

                    ownerisUser = _GetOwnerisUser(ownerid);
                    SetOwner(uId.ToString(), ownerid, ownerisUser);

                    var userinviteId = (from us in this.mdb.AHSAspnetUsers
                                        where (us.Username.ToLower() == user.ToLower())
                                        select us.Userid).FirstOrDefault();


                    //Add UsersInProject
                    if (idPrjRoles != null)
                    {
                        AddUserToProjects(uId, userinviteId.ToString(), idPrjRoles, ref msgError);
                    }

                    //Add UsersInOrganization
                    if (idOrgs != null)
                    {
                        AddOrgsToUser(uId, userinviteId.ToString(), idOrgs, ref msgError);
                    }

                    return uId;
                }
                else
                {
                    msgError = status.ToString();
                    return null;
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUser error {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update user for SA
        /// </summary>
        /// <param name="user"></param>
        /// <param name="userId"></param>
        /// <param name="name"></param>
        /// <param name="phone"></param>
        /// <param name="password"></param>
        /// <param name="email"></param>
        /// <param name="ownerid"></param>
        /// <param name="isApproved"></param>
        /// <param name="idOrgs"></param>
        /// <param name="idOrgDels"></param>
        /// <param name="idPrjRoles"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public int UpdateUser(string user, string userId, string name, string phone, string password, string email, string ownerid, string isApproved, string[] idOrgs, string[] idOrgDels, string[] idPrjRoles, ref string msgError)
        {
            try
            {
                Guid uId;
                bool ownerisUser = true;

                if (!Guid.TryParse(userId, out uId))
                {
                    msgError = string.Format("{0} is not validate id user", userId);
                    return -1;
                }
                //Update membership user
                MembershipUser updateUser = Membership.GetUser(uId);

                if (password != null)
                {
                    string oldpass = updateUser.ResetPassword();
                    updateUser.ChangePassword(oldpass, password);
                }

                if (email != null)
                {
                    updateUser.Email = email;
                }

                Membership.UpdateUser(updateUser);

                //Update Profile
                ProfileBase pb = ProfileBase.Create(updateUser.UserName);
                pb.SetPropertyValue("Phone", phone);
                pb.SetPropertyValue("Name", name);
                pb.Save();


                // Set Ower to User
                // if ownerid is UserId  the ownerisUser = true; then ownerisUser = false
                if (ownerid != null)
                {
                    ownerisUser = _GetOwnerisUser(ownerid);
                    SetOwner(userId, ownerid, ownerisUser);

                }

                //Update UsersInOrganization
                if (idOrgDels != null) RemoveOrgsFromUser(idOrgDels, uId);

                var userinviteId = (from us in this.mdb.AHSAspnetUsers
                                    where (us.Username.ToLower() == user.ToLower())
                                    select us.Userid).FirstOrDefault();


                if (idOrgs != null) AddOrgsToUser(uId, userinviteId.ToString(), idOrgs, ref msgError);

                //Update UsersInProject
                if (idOrgDels != null) RemoveProjectsFromUser(idOrgDels, uId);

                if (idPrjRoles != null) AddUserToProjects(uId, userinviteId.ToString(), idPrjRoles, ref msgError);

                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.UpdateUser error {0}", ex);
                msgError = ex.Message;

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update Prj and Role
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="idPrjRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int UpdatePrjAndRole(Guid userId, string[] idPrjRoles, ref string message)
        {
            try
            {
                foreach (var idPrjRole in idPrjRoles)
                {
                    string[] arrPrjRole = idPrjRole.Split('^');
                    int prjId = int.Parse(arrPrjRole[0]);

                    var userrole = (from uip in this.mdb.AHSUserInProjects
                                    where ((uip.Userid == userId) && (uip.Projectid == prjId)) &&
                                          (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                    select uip).FirstOrDefault();

                    if (userrole != null)
                    {
                        if ((arrPrjRole[2] != "null") && (arrPrjRole[2].ToString() != "00000000-0000-0000-0000-000000000000"))
                        {
                            userrole.Roleid = Guid.Parse(arrPrjRole[2]);
                        }
                        else
                        {
                            userrole.Roleid = null;
                        }
                    }

                }
                this.mdb.SubmitChanges();
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.UpdatePrjAndRole error {0}", ex);
                message = "UserInProjectManager: Unable to Update Prj And Role to user";

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Search User by SA for keyword
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public List<User> SearchUserSA(string keyword, ref string msgError)
        {
            try
            {

                List<User> ret = new List<User>();

                //string.IsNullOrEmpty(keyword)

                var users = (from ms in this.mdb.AHSAspnetMemberships
                             join us in this.mdb.AHSAspnetUsers on ms.Userid equals us.Userid
                             where ((ms.Email.ToLower().Contains(keyword) || us.Username.ToLower().Contains(keyword))) &&
                                    (us.Username.ToLower() == "sa")
                             orderby (us.Username)
                             select new { userid = us.Userid, username = us.Username, email = ms.Email, isapproved = ms.Isapproved, isLockedout = ms.Islockedout, ownerid = ms.Ownerid, ownerisuser = ms.Ownerisuser }).
                            Union(from ms in this.mdb.AHSAspnetMemberships
                                  join us in this.mdb.AHSAspnetUsers on ms.Userid equals us.Userid
                                  join uip in this.mdb.AHSUserInProjects on ms.Userid equals uip.Userid
                                  where ((ms.Email.ToLower().Contains(keyword) || us.Username.ToLower().Contains(keyword))) &&
                                         (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                  orderby (us.Username)
                                  select new { userid = us.Userid, username = us.Username, email = ms.Email, isapproved = ms.Isapproved, isLockedout = ms.Islockedout, ownerid = ms.Ownerid, ownerisuser = ms.Ownerisuser }).Distinct();

                if (users == null)
                {
                    return null;
                }

                foreach (var item in users)
                {
                    var user = new User();

                    user.UserName = item.username;
                    user.Email = item.email;
                    user.UserId = item.userid;
                    if (item.isapproved.HasValue)
                    {
                        user.IsApproved = item.isapproved.Value == 1 ? true : false;
                    }
                    else
                    {
                        user.IsApproved = false;
                    }

                    if ((item.isLockedout.HasValue) && (user.IsApproved)) 
                    {
                        user.IsApproved = item.isLockedout.Value == 0 ? true : false;
                    }

                    ProfileBase pb = ProfileBase.Create(item.username);
                    var phone = pb.GetPropertyValue("Phone");
                    if (phone != null)
                        user.Phone = phone.ToString();
                    else
                        user.Phone = "";

                    var name = pb.GetPropertyValue("Name");
                    if (name != null)
                        user.Name = name.ToString();
                    else
                        user.Name = "";

                    user.OwnerID = item.ownerid;
                    user.OwnerIsUser = item.ownerisuser;

                    user.ApplicationName = this.ApplicationName;
                    ret.Add(user);
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.SearchUserSA error {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Action invite User to Org
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="orgId"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public bool ActionInviteOrganizationsList(string userId, string orgId, int status)
        {
            try
            {
                var query = (from uio in this.mdb.AHSUsersInOrganizations
                             join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid
                             where (uio.UserId == Guid.Parse(userId)) && (uio.OrgId == Guid.Parse(orgId)) &&
                                   (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                             select uio).FirstOrDefault();

                query.Status = status;

                if (status == 1)
                {
                    query.IsInvite = false;
                }

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.ActionInviteOrganizationsList error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Action Invite ProjectsList
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="prjId"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public bool ActionInviteProjectsList(string userId, int prjId, int status)
        {
            try
            {
                var query = (from uip in this.mdb.AHSUserInProjects
                             where (uip.Userid == Guid.Parse(userId)) && (uip.Projectid == prjId) &&
                                   (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                             select uip).FirstOrDefault();


                query.Status = status;

                if (status == 1)
                {
                    //Accept join to project
                    //Check join into Organization Empower
                    var prjType = (from prj in this.mdb.AHSMainProjects
                                   where (prj.Id == prjId) &&
                                     (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   select prj.AHSProjectType.ApplicationName).Distinct();

                    if (prjType != null && prjType.Count() > 0)
                    {
                        //Find Organization Empower
                        var findOrg = from orgs in this.mdb.AHSOrganizationEmpowerForApps
                                      where orgs.ApplicationName == prjType.FirstOrDefault()
                                      select orgs.OrganID;

                        if (findOrg != null && findOrg.Count() > 0)
                        {
                            var org = findOrg.FirstOrDefault();

                            if (org != null)
                            {
                                //Add user to organization
                                //Check User Exist in Organization
                                var findUser = (from user in this.mdb.AHSUsersInOrganizations
                                                join uip in this.mdb.AHSUserInProjects on user.UserId equals uip.Userid
                                                where user.UserId == Guid.Parse(userId) && user.OrgId == org &&
                                                     uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                                select user).Distinct();

                                if (findUser == null || findUser.Count() <= 0)
                                {
                                    //Not exist => add
                                    AHSDbContext.AHSUsersInOrganization uio = new AHSUsersInOrganization();

                                    uio.OrgId = org;
                                    uio.UserId = Guid.Parse(userId);
                                    uio.IsInvite = false;
                                    uio.Status = 1;

                                    this.mdb.AHSUsersInOrganizations.InsertOnSubmit(uio);
                                    this.mdb.SubmitChanges();
                                }

                            }
                        }
                    }
                }

                if (status == 1)
                {
                    query.IsInvite = false;
                }

                this.mdb.SubmitChanges();
                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.ActionInviteProjectsList error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get list object UserInProject by SA for userId
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<UserInProject> GetInviteProjectsListBySA(string userId, ref string msgError)
        {
            try
            {
                List<UserInProject> ret = new List<UserInProject>();


                var query = (from uip in this.mdb.AHSUserInProjects
                             join mp in this.mdb.AHSMainProjects on uip.Projectid equals mp.Id
                             where (uip.Userid == Guid.Parse(userId) && uip.IsInvite == true && (uip.Status == -1 || uip.Status == null)) &&
                                     (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                             orderby (mp.Name)
                             select new { UserId = uip.Userid, PrjId = uip.Projectid, PrjName = mp.Name, IsInvite = uip.IsInvite, Status = uip.Status, UserInviteId = uip.UserInvite }).Distinct();

                foreach (var item in query)
                {
                    UserInProject prj = new UserInProject();

                    prj.UserId = item.UserId;
                    prj.ProjectId = item.PrjId;
                    prj.ProjectName = item.PrjName;
                    prj.IsInvite = item.IsInvite;
                    prj.Status = item.Status;
                    prj.UserInvite = item.UserInviteId;

                    ret.Add(prj);
                    prj = null;

                }
                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetInviteProjectsListBySA error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<UserInProject> GetProjectListFromUserSA(string userId, ref string msgError)
        {
            try
            {
                List<UserInProject> ret = new List<UserInProject>();
                Guid uId;
                if (!Guid.TryParse(userId, out uId))
                    return null;

                var list = (from uip in this.mdb.AHSUserInProjects
                            orderby uip.AHSMainProject.Name
                            where (uip.Userid == uId) &&
                                 (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                            select new { uip, uip.AHSMainProject.Name }).Distinct();

                foreach (var item in list)
                {

                    var obj = new UserInProject();
                    obj.UserId = item.uip.Userid;
                    obj.ProjectId = item.uip.Projectid;
                    obj.IsInvite = item.uip.IsInvite;
                    obj.Status = item.uip.Status;
                    obj.UserInvite = item.uip.UserInvite;
                    obj.RoleId = item.uip.Roleid;

                    obj.UserName = item.uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username;

                    obj.ProjectName = item.uip.AHSMainProject.Name;
                    obj.ProjectTypeId = item.uip.AHSMainProject.AHSProjectType.Id;
                    obj.isPM = item.uip.AHSMainProject.AHSProjectType.IsPM.HasValue ? item.uip.AHSMainProject.AHSProjectType.IsPM.Value : false;

                    if (obj.RoleId != null) obj.RoleName = item.uip.AHSAspnetRole.Roledisplay; else obj.RoleName = "";

                    ret.Add(obj);
                }

                return ret;
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetProjectListFromUserSA {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// 
        /// Get list role admin by self
        /// </summary>
        /// <returns></returns>
        public List<Guid> GetListRoleAdminSelf(Guid userid, bool isAdmin)
        {
            List<Guid> lst = new List<Guid>();

            try
            {
                if (!isAdmin)
                {
                    //Get role admin for user in project
                    var roles = (from r in this.mdb.AHSUserInProjects
                                 where r.Userid == userid && r.Status == 1 && r.AHSAspnetRole.Isrolepermit.HasValue && r.AHSAspnetRole.Isrolepermit.Value &&
                                        (r.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select new { roleid = r.AHSAspnetRole.Roleid }).Distinct();

                    foreach (var r in roles)
                    {
                        lst.Add(r.roleid);
                    }

                    //Get role admin for user via organization in project
                    var rolesviaorgan = (from r in this.mdb.AHSOrganizationInProjects
                                         join uio in this.mdb.AHSUsersInOrganizations on r.Orgid equals uio.OrgId
                                         where uio.UserId == userid && uio.Status == 1 && r.Status == 1 &&
                                             r.AHSAspnetRole.Isrolepermit.HasValue && r.AHSAspnetRole.Isrolepermit.Value &&
                                             (r.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                         select new { roleid = r.AHSAspnetRole.Roleid }).Distinct();
                    foreach (var r in rolesviaorgan)
                    {
                        lst.Add(r.roleid);
                    }

                    //Get role admin for user in organization
                    var rolesinorgan = (from r in this.mdb.AHSUsersInOrganizations
                                        join oip in this.mdb.AHSOrganizationInProjects on r.OrgId equals oip.Orgid
                                        where r.UserId == userid && r.Status == 1 && r.AHSOrganization.AHSAspnetRole.Isrolepermit.HasValue &&
                                             r.AHSOrganization.AHSAspnetRole.Isrolepermit.Value && r.AHSOrganization.OrgType == 1 &&
                                             (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                        select new { roleid = r.AHSAspnetRole.Roleid }).Distinct();
                    foreach (var r in rolesinorgan)
                    {
                        lst.Add(r.roleid);
                    }
                }
                else
                {
                    var roles = (from r in this.mdb.AHSAspnetRoles
                                 where r.Isrolepermit.HasValue && r.Isrolepermit.Value &&
                                     (r.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select r).Distinct();
                    foreach (var r in roles)
                    {
                        lst.Add(r.Roleid);
                    }
                }
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListRoleAdminSelf {0}", ex);

                return null;
            }

            return lst;
        }

        /// <summary>
        /// Get list projectype admin by self
        /// </summary>
        /// <returns></returns>
        public List<ProjectTypeRoleType> GetListProjectTypeAndRoleAdminSelf(Guid userid, bool isAdmin)
        {
            List<ProjectTypeRoleType> lst = new List<ProjectTypeRoleType>();

            try
            {
                if (!isAdmin)
                {
                    //Get project type admin for user in project
                    var roles = (from r in this.mdb.AHSUserInProjects
                                 where r.Userid == userid && r.Status == 1 && r.AHSAspnetRole.Isrolepermit.HasValue && r.AHSAspnetRole.Isrolepermit.Value &&
                                         r.AHSAspnetRole.Adminforprojectype.HasValue && r.AHSAspnetRole.Roletype.HasValue &&
                                         (r.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select r).Distinct();

                    foreach (var r in roles)
                    {
                        lst.Add(new ProjectTypeRoleType(r.AHSAspnetRole.Adminforprojectype.Value, r.AHSAspnetRole.Roletype.Value));
                    }

                    //Get role admin for user via organization in project
                    var rolesviaorgan = (from r in this.mdb.AHSOrganizationInProjects
                                         join uio in this.mdb.AHSUsersInOrganizations on r.Orgid equals uio.OrgId
                                         where uio.UserId == userid && uio.Status == 1 && r.Status == 1 &&
                                             r.AHSAspnetRole.Isrolepermit.HasValue && r.AHSAspnetRole.Isrolepermit.Value &&
                                             r.AHSAspnetRole.Adminforprojectype.HasValue && r.AHSAspnetRole.Roletype.HasValue &&
                                             (r.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                         select r).Distinct();

                    foreach (var r in rolesviaorgan)
                    {
                        lst.Add(new ProjectTypeRoleType(r.AHSAspnetRole.Adminforprojectype.Value, r.AHSAspnetRole.Roletype.Value));
                    }

                    //Get role admin for user in organization empowering
                    var rolesinorgan = (from r in this.mdb.AHSUsersInOrganizations
                                        join oip in this.mdb.AHSOrganizationInProjects on r.OrgId equals oip.Orgid
                                        where r.UserId == userid && r.Status == 1 &&
                                        r.AHSOrganization.AHSAspnetRole.Isrolepermit.HasValue && r.AHSOrganization.AHSAspnetRole.Isrolepermit.Value &&
                                        r.AHSOrganization.OrgType == 1 && r.AHSAspnetRole.Adminforprojectype.HasValue && r.AHSAspnetRole.Roletype.HasValue &&
                                        (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                        select r).Distinct();

                    foreach (var r in rolesinorgan)
                    {
                        lst.Add(new ProjectTypeRoleType(r.AHSAspnetRole.Adminforprojectype.Value, r.AHSAspnetRole.Roletype.Value));
                    }
                }
                else
                {
                    var roles = (from r in this.mdb.AHSAspnetRoles
                                 where r.Isrolepermit.HasValue && r.Isrolepermit.Value &&
                                       r.Adminforprojectype.HasValue && r.Roletype.HasValue &&
                                 (r.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select r).Distinct();
                    foreach (var r in roles)
                    {
                        lst.Add(new ProjectTypeRoleType(r.Adminforprojectype.Value, r.Roletype.Value));
                    }
                }
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListProjectTypeAndRoleAdminSelf {0}", ex);

                return null;
            }

            return lst;
        }

        /// <summary>
        /// Get project type by myself
        /// </summary>
        /// <returns></returns>
        public List<int> GetListProjectTypeSelf(Guid userId, bool isAdmin)
        {
            List<int> lst = new List<int>();

            try
            {
                if (!isAdmin)
                {
                    //Get role type for user in project
                    var roles = (from r in this.mdb.AHSUserInProjects
                                 where r.Userid == userId && r.Status == 1 &&
                                     r.AHSAspnetRole.Isrolepermit.HasValue && r.AHSAspnetRole.Isrolepermit.Value &&
                                     r.AHSAspnetRole.Adminforprojectype.HasValue &&
                                     (r.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select r).Distinct();

                    foreach (var r in roles)
                    {
                        lst.Add(r.AHSAspnetRole.Adminforprojectype.Value);
                    }

                    //Get role type for user via organization in project
                    var rolesviaorgan = (from r in this.mdb.AHSOrganizationInProjects
                                         join uio in this.mdb.AHSUsersInOrganizations on r.Orgid equals uio.OrgId
                                         where uio.UserId == userId && uio.Status == 1 && r.Status == 1 &&
                                               r.AHSAspnetRole.Isrolepermit.HasValue && r.AHSAspnetRole.Isrolepermit.Value &&
                                               r.AHSAspnetRole.Adminforprojectype.HasValue &&
                                               (r.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                         select r).Distinct();

                    foreach (var r in rolesviaorgan)
                    {
                        lst.Add(r.AHSAspnetRole.Adminforprojectype.Value);
                    }

                    //Get role type for user in organization
                    var rolesinorgan = (from r in this.mdb.AHSUsersInOrganizations
                                        join oip in this.mdb.AHSOrganizationInProjects on r.OrgId equals oip.Orgid
                                        where r.UserId == userId && r.Status == 1 && r.AHSOrganization.AHSAspnetRole.Isrolepermit.HasValue &&
                                             r.AHSOrganization.AHSAspnetRole.Isrolepermit.Value && r.AHSOrganization.OrgType == 1 &&
                                             r.AHSOrganization.AHSAspnetRole.Adminforprojectype.HasValue &&
                                             (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                        select r).Distinct();

                    foreach (var r in rolesinorgan)
                    {
                        lst.Add(r.AHSOrganization.AHSAspnetRole.Adminforprojectype.Value);
                    }
                }
                else
                {
                    var roles = (from r in this.mdb.AHSProjectTypes
                                 where r.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                 select r).Distinct();

                    foreach (var r in roles)
                    {
                        lst.Add(r.Id);
                    }
                }

            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListProjectTypeSelf {0}", ex);

                return null;
            }

            return lst;
        }

        /// <summary>
        /// Add Users To Project
        /// </summary>
        /// <param name="idPrj"></param>
        /// <param name="userinviteId"></param>
        /// <param name="message"></param>
        /// <param name="idUserRoles"></param>
        /// <returns></returns>
        public int AddUsersToProject(int idPrj, Guid userinviteId, ref string message, params string[] idUserRoles)
        {
            try
            {
                //Guid userId;
                string _message = String.Empty;
                ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                string root = alm.GetLinkByApplication();

                foreach (var idUserRole in idUserRoles)
                {
                    string[] arrUserRole = idUserRole.Split('^');
                    Guid uUserId;
                    Guid uRoleId;

                    // Invite User to this project
                    //(arrUserRole[1] == "1")
                    if (!Guid.TryParse(arrUserRole[0], out uUserId))
                    {
                        //arrUserRole[0] is email => Check email exist in memberships. if not exist then send email invitation

                        var email = arrUserRole[0];

                        ProjectManager manager = new ProjectManager(this.ApplicationName);

                        if (!(Guid.TryParse(arrUserRole[2], out uRoleId)))
                        {
                            uRoleId = Guid.Parse("00000000-0000-0000-0000-000000000000");
                        }

                        var ret = manager.InviteUserToProjectByEmail(null, email, idPrj, userinviteId, uRoleId); //Guid.Parse("00000000-0000-0000-0000-000000000000")

                        var activeLink = String.Format(@" <a href='" + root + "Account/Register?codes=" + ret.Code + "'>here</a> ");
                        var cs4 = String.Format(@" <a href='" + root + "'>Collaboration System</a>");
                        string body = String.Format(@"Click" + activeLink + "to register your account to " + cs4);

                        NotificationUtils.SendMail("CS Admin", email, "Invite", body, MailType.ExternalNotification);
                        message = _message;
                    }
                    else
                    { // Assign User to this project

                        var userrole2 = (from uip in this.mdb.AHSUserInProjects
                                         where ((uip.Userid == Guid.Parse(arrUserRole[0].ToString())) && (uip.Projectid == idPrj)) &&
                                               (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                         select uip).FirstOrDefault();
                        if (userrole2 == null)
                        {
                            var csuserinprj = new AHSDbContext.AHSUserInProject();
                            csuserinprj.Projectid = idPrj;
                            csuserinprj.Userid = Guid.Parse(arrUserRole[0].ToString());

                            if ((arrUserRole[2] != "null") && (arrUserRole[2].ToString() != "00000000-0000-0000-0000-000000000000"))
                            {
                                csuserinprj.Roleid = Guid.Parse(arrUserRole[2].ToString());
                            }
                            else
                            {
                                csuserinprj.Roleid = null;
                            }

                            csuserinprj.UserInvite = userinviteId;

                            csuserinprj.IsInvite = false;
                            csuserinprj.Status = 1;

                            this.mdb.AHSUserInProjects.InsertOnSubmit(csuserinprj);

                            // Hiện tại chưa có phần AddKnown trong CS
                            //MainProjectManager pm = new MainProjectManager();
                            //pm.AddKnown(csuserinprj.Userid, csuserinprj.Projectid, false);
                            //if (csuserinprj.UserInvite != null) pm.AddKnown(csuserinprj.UserInvite.Value, csuserinprj.Projectid, false);

                        }
                        else
                        {
                            // Update
                            if ((arrUserRole[2] != "null") && (arrUserRole[2].ToString() != "00000000-0000-0000-0000-000000000000"))
                            {
                                userrole2.Roleid = Guid.Parse(arrUserRole[2].ToString());
                            }
                            else
                            {
                                userrole2.Roleid = null;
                            }

                            userrole2.UserInvite = userinviteId;

                            userrole2.IsInvite = false;
                            userrole2.Status = 1;
                        }
                    }
                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUsersToProject error {0}", ex);
                message = ex.Message;

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get list user IsApproved or IsLockedOut
        /// </summary>
        /// <returns></returns>
        public List<User> GetListUser()
        {
            try
            {
                List<User> ret = new List<User>();
                var users = (from ms in this.mdb.AHSAspnetMemberships
                             join us in this.mdb.AHSAspnetUsers on ms.Userid equals us.Userid
                             where (ms.Isapproved.HasValue && ms.Isapproved.Value == 1) && (ms.Islockedout.Value == 0) &&
                                    (us.Username.ToLower() == "sa")
                             orderby ms.AHSAspnetUser.Username
                             select new { userid = ms.Userid, username = ms.AHSAspnetUser.Username, email = ms.Email, isapproved = ms.Isapproved, isLockedout = ms.Islockedout, ownerid = ms.Ownerid, ownerisuser = ms.Ownerisuser }).
                             Union(from ms in this.mdb.AHSAspnetMemberships
                                   join uip in this.mdb.AHSUserInProjects on ms.Userid equals uip.Userid
                                   where (ms.Isapproved.HasValue && ms.Isapproved.Value == 1) && (ms.Islockedout.Value == 0) &&
                                          (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   orderby ms.AHSAspnetUser.Username
                                   select new { userid = ms.Userid, username = ms.AHSAspnetUser.Username, email = ms.Email, isapproved = ms.Isapproved, isLockedout = ms.Islockedout, ownerid = ms.Ownerid, ownerisuser = ms.Ownerisuser }).Distinct();

                if (users == null)
                {
                    return null;
                }

                foreach (var item in users)
                {
                    var user = new User();

                    user.UserName = item.username;
                    user.Email = item.email;
                    user.UserId = item.userid;
                    if (item.isapproved.HasValue)
                    {
                        user.IsApproved = item.isapproved.Value == 1 ? true : false;
                    }
                    else
                    {
                        user.IsApproved = false;
                    }

                    if ((item.isLockedout.HasValue) && (user.IsApproved))
                    {
                        user.IsApproved = item.isLockedout.Value == 0 ? true : false;
                    }

                    ProfileBase pb = ProfileBase.Create(item.username);
                    var phone = pb.GetPropertyValue("Phone");
                    if (phone != null)
                        user.Phone = phone.ToString();
                    else
                        user.Phone = "";

                    var name = pb.GetPropertyValue("Name");
                    if (name != null)
                        user.Name = name.ToString();
                    else
                        user.Name = "";

                    user.OwnerID = item.ownerid;
                    user.OwnerIsUser = item.ownerisuser;

                    user.ApplicationName = this.ApplicationName;
                    ret.Add(user);
                }
                return ret;

            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetListUser error {0}", ex);

                return null;
            }
        }


        /// <summary>
        /// Author: Hoang Van tai
        /// Tạo đồng bộ user thuộc project vào UserInApplication
        /// </summary>
        /// <returns></returns>
        private bool _SynServiceUserInProject()
        {
            try
            {
                // User thuộc project
                var user = from uip in this.mdb.AHSUserInProjects
                           where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select uip;

                if (user != null)
                {
                    foreach (var item in user)
                    {

                        if (!this.IsExistUser(item.Userid))
                        {
                            AHSUserInApplication uia = new AHSUserInApplication();

                            uia.UserID = item.Userid;
                            uia.ApplicationName = this.ApplicationName;

                            this.mdb.AHSUserInApplications.InsertOnSubmit(uia);
                        }
                    }
                    this.mdb.SubmitChanges();
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager._SynServiceUserInProject error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Tạo đồng bộ user thuộc Organization thuộc Project vào UserInApplication
        /// </summary>
        /// <returns></returns>
        private bool _SynServiceUserInOrganization()
        {
            try
            {
                // User thuộc organization vaf organization thuộc Project 
                var user = from uio in this.mdb.AHSUsersInOrganizations
                           join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid
                           where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select uio;

                if (user != null)
                {
                    foreach (var item in user)
                    {
                        if (!this.IsExistUser(item.UserId))
                        {
                            AHSUserInApplication uia = new AHSUserInApplication();

                            uia.UserID = item.UserId;
                            uia.ApplicationName = this.ApplicationName;

                            this.mdb.AHSUserInApplications.InsertOnSubmit(uia);
                        }
                    }
                    this.mdb.SubmitChanges();
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager._SynServiceUserInOrganization error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Tạo Service đồng bộ người dùng trong Application
        /// </summary>
        /// <returns></returns>
        public bool SynServiceUserToApplication()
        {
            try
            {
                // Tạo đồng bộ user thuộc project
                _SynServiceUserInProject();

                // User thuộc Organization và organization thuộc project
                _SynServiceUserInOrganization();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.SynServiceUserToApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get list user for project 
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<User> GetUsersForProject(int projectId)
        {
            try
            {
                List<User> ret = new List<User>();

                
                var uips = (from uip in this.mdb.AHSUserInProjects
                            where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                 (uip.Projectid == projectId)
                            select new { user = uip.AHSAspnetMembership_Userid.AHSAspnetUser, roleid = uip.Roleid, roleName = uip.AHSAspnetRole.Rolename }).Distinct();

                if (uips == null) 
                {
                    return null ;
                }

                foreach (var item in uips)
                {

                    User obj = new User();

                    obj.UserId = item.user.Userid;
                    obj.UserName = item.user.Username;
                    obj.RoleId = item.roleid;

                    if (obj.RoleId != null) obj.RoleName = item.roleName; else obj.RoleName = "";

                    ret.Add(obj);
                }
                    
                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.GetUsersForProject error {0}", ex);

                return null;
            }
        }
    }
}